home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 2.iso / dist / fw_glimpse.idb / usr / freeware / src / glimpse-3.0 / agrep / maskgen.c.z / maskgen.c
C/C++ Source or Header  |  1997-09-09  |  6KB  |  243 lines

  1. /* Copyright (c) 1994 Sun Wu, Udi Manber, Burra Gopal.  All Rights Reserved. */
  2. #include "agrep.h"
  3.  
  4. extern unsigned D_endpos, endposition, Init1, wildmask;
  5. extern Mask[], Bit[], Init[], NO_ERR_MASK;
  6. extern int AND, REGEX, NOUPPER, D_length;
  7. extern unsigned char Progname[];
  8. extern int agrep_initialfd;
  9. extern int EXITONERROR;
  10. extern int errno;
  11.  
  12. int
  13. maskgen(Pattern, D)
  14. unsigned char *Pattern; 
  15. int D;
  16. {
  17.     struct term { 
  18.         int flag; 
  19.         unsigned char class[WORD];
  20.     } 
  21.     position[WORD+10];
  22.     unsigned char c;
  23.  
  24.     int i, j, k, l, M, OR=0, EVEN = 0, base, No_error;
  25.  
  26. #ifdef    DEBUG
  27.     fprintf(stderr, "maskgen: len=%d, pat=%s, D=%d\n", strlen(Pattern), Pattern, D);
  28. #endif
  29.     for(i=0; i<WORD; i++) position[i].class[0] = '\0';
  30.     for(i=0; i<WORD; i++) position[i].flag = 0;
  31.     wildmask = NO_ERR_MASK = endposition = 0;
  32.     No_error = 0;
  33.     if ((M = strlen(Pattern)) <= 0) return 0;
  34.     if(NOUPPER) {
  35.         for(i=0; i<M; i++) if(isalpha((int)Pattern[i])) 
  36.             if (isupper((int)Pattern[i])) Pattern[i] = tolower((int)Pattern[i]);
  37.     }
  38. #ifdef DEBUG
  39.     for(i=0; i<M; i++) printf(" %d", Pattern[i]);
  40.     printf("\n");
  41. #endif
  42.     for (i=0, j=1; i< M; i++)
  43.     {
  44.         switch (Pattern[i])
  45.         {
  46.         case WILDCD : 
  47.             if(REGEX) {
  48.                 position[j].class[0] = '.';
  49.                 position[j].class[1] = '.';
  50.                 position[j++].class[2] = '\0'; 
  51.                 break;
  52.             }
  53.             wildmask = wildmask | Bit[j-1]; 
  54.             break;
  55.         case STAR   : 
  56.             break; 
  57.         case ORSYM  : 
  58.             break; 
  59.         case LPARENT: 
  60.             break;
  61.         case RPARENT: 
  62.             break;
  63.         case LANGLE : 
  64.             No_error = ON; 
  65.             EVEN++;
  66.             break;
  67.         case RANGLE : 
  68.             No_error = OFF; 
  69.             EVEN--;
  70.             if(EVEN < 0) {
  71.                 fprintf(stderr, "%s: unmatched '<', '>' (use \\<, \\> to search for <, >)\n", Progname);
  72.                 if (!EXITONERROR) {
  73.                     errno = AGREP_ERROR;
  74.                     return -1;
  75.                 }
  76.                 else exit(2);
  77.             }
  78.             break;
  79.         case LRANGE : 
  80.             if(No_error == ON) NO_ERR_MASK = NO_ERR_MASK | Bit[j]; 
  81.             i=i+1; 
  82.             if (Pattern[i] == NOTSYM) { 
  83.                 position[j].flag = Compl; 
  84.                 i++; 
  85.             }
  86.             k=0;
  87.             while (Pattern[i] != RRANGE && i < M)
  88.             { 
  89.                 if(Pattern[i] == HYPHEN) 
  90.                 { 
  91.                     position[j].class[k-1] = Pattern[i+1]; 
  92.                     i=i+2; 
  93.                 }
  94.                 else { 
  95.                     position[j].class[k] = position[j].class[k+1] = Pattern[i];
  96.                     k = k+2; 
  97.                     i++;
  98.                 }
  99.             }
  100.             if(i == M) {
  101.                 fprintf(stderr, "%s: unmatched '[', ']' (use \\[, \\] to search for [, ])\n", Progname);
  102.                 if (!EXITONERROR) {
  103.                     errno = AGREP_ERROR;
  104.                     return -1;
  105.                 }
  106.                 else exit(2);
  107.             }
  108.             position[j].class[k] = '\0';
  109.             j++; 
  110.             break;
  111.         case RRANGE : 
  112.             fprintf(stderr, "%s: unmatched '[', ']' (use \\[, \\] to search for [, ])\n", Progname);
  113.             if (!EXITONERROR) {
  114.                 errno = AGREP_ERROR;
  115.                 return -1;
  116.             }
  117.             else exit(2);
  118.             break;     
  119.         case ORPAT  : 
  120.             if(REGEX == ON || AND == ON) {
  121.                 fprintf(stderr, "illegal pattern: cannot handle OR (',') and AND (';')/regular-expressions simultaneously\n");
  122.                 if (!EXITONERROR) {
  123.                     errno = AGREP_ERROR;
  124.                     return -1;
  125.                 }
  126.                 else exit(2);
  127.             }
  128.             OR = ON;
  129.             position[j].flag = 2; 
  130.             position[j].class[0] = '\0';
  131.             endposition = endposition | Bit[j++]; 
  132.             break;
  133.         case ANDPAT : 
  134.             position[j].flag = 2; 
  135.             position[j].class[0] = '\0'; 
  136.             if(j > D_length) AND = ON;
  137.             if(OR || (REGEX == ON && j>D_length)) {
  138.                 fprintf(stderr, "illegal pattern: cannot handle AND (';') and OR (',')/regular-expressions simultaneously\n");
  139.                 if (!EXITONERROR) {
  140.                     errno = AGREP_ERROR;
  141.                     return -1;
  142.                 }
  143.                 else exit(2);
  144.             }
  145.             endposition = endposition | Bit[j++]; 
  146.             break;
  147.             /*
  148.                 case ' '    : if (Pattern[i-1] == ORPAT || Pattern[i-1] == ANDPAT) break;
  149.                               if(No_error == ON) NO_ERR_MASK = NO_ERR_MASK | Bit[j];
  150.                               position[j].flag = 0;
  151.                               position[j].class[0] = position[j].class[1] = Pattern[i];
  152.                               position[j++].class[2] = '\0';  break;
  153.             */
  154.         case '\n'   : 
  155.             NO_ERR_MASK = NO_ERR_MASK | Bit[j];
  156.             position[j].class[0] = position[j].class[1] = '\n';
  157.             position[j++].class[2] = '\0'; 
  158.             break;
  159.         case WORDB  : 
  160.             NO_ERR_MASK = NO_ERR_MASK | Bit[j];
  161.             position[j].class[0] = 1;
  162.             position[j].class[1] = 47;
  163.             position[j].class[2] = 58;
  164.             position[j].class[3] = 64;
  165.             position[j].class[4] = 91;
  166.             position[j].class[5] = 96;
  167.             position[j].class[6] = 123;
  168.             position[j].class[7] = 127;
  169.             position[j++].class[8] = '\0';
  170.             break;    
  171.         case NNLINE : 
  172.             NO_ERR_MASK |= Bit[j];
  173.             position[j].class[0] = position[j].class[1] = '\n';
  174.             position[j].class[2] = position[j].class[3] = NNLINE;
  175.             position[j++].class[4] = '\0';
  176.             break;
  177.         default : 
  178.             if(No_error == ON) NO_ERR_MASK = NO_ERR_MASK | Bit[j];
  179.             position[j].flag = 0;
  180.             position[j].class[0] = position[j].class[1] = Pattern[i];
  181.             position[j++].class[2] = '\0'; 
  182.         }
  183.         if(j > WORD) {
  184.             fprintf(stderr, "%s: pattern too long (has > %d chars)\n", Progname, WORD);
  185.             if (!EXITONERROR) {
  186.                 errno = AGREP_ERROR;
  187.                 return -1;
  188.             }
  189.             else exit(2);
  190.         }
  191.     }
  192.     if (EVEN != 0) {
  193.         fprintf(stderr, "%s: unmatched '<', '>' (use \\<, \\> to search for <, >)\n", Progname);
  194.         if (!EXITONERROR) {
  195.             errno = AGREP_ERROR;
  196.             return -1;
  197.         }
  198.         else exit(2);
  199.     }
  200.     M = j - 1;
  201.     base = WORD - M;
  202.     wildmask = (wildmask >> base);
  203.     endposition = (endposition >> base);
  204.     NO_ERR_MASK = (NO_ERR_MASK >> 1) & (~Bit[1]);
  205.     NO_ERR_MASK = ~NO_ERR_MASK >> (base-1);
  206.     for (i=1; i<= WORD - M ; i++) Init[0] = Init[0] | Bit[i];
  207.     Init[0] = Init[0] | endposition;
  208.     /* not necessary for INit[i], i>0, */
  209.     /* but at every begining of the matching process append one
  210.                     no-match character to initialize the error vectors */
  211.     endposition = ( endposition << 1 ) + 1;
  212.     Init1 = (Init[0] | wildmask | endposition) ;
  213.     D_endpos = ( endposition >> ( M - D_length ) ) << ( M - D_length);
  214.     endposition = endposition ^ D_endpos;
  215. #ifdef DEBUG
  216.     printf("endposition: %o\n", endposition);
  217.     printf("no_err_mask: %o\n", NO_ERR_MASK);
  218. #endif
  219.     for(c=0, i=0; i < MAXSYM; c++, i++)
  220.     {
  221.         for (k=1, l=0; k<=M ; k++, l=0)  {
  222.             while (position[k].class[l] != '\0') {
  223.                 if (position[k].class[l] == NOCARE && (c != '\n' || REGEX) ) 
  224.                 {  
  225.                     Mask[c] = Mask[c] | Bit[base + k]; 
  226.                     break; 
  227.                 }
  228.                 if (c >= position[k].class[l] && c <= position[k].class[l+1])
  229.                 {  
  230.                     Mask[c] = Mask[c] | Bit[base + k]; 
  231.                     break; 
  232.                 }
  233.                 l = l + 2;  
  234.             }
  235.             if (position[k].flag == Compl) Mask[c] = Mask[c] ^ Bit[base+k];
  236.         }
  237.     }
  238.     if(NOUPPER) for(i=0; i<MAXSYM; i++)
  239.         if (isupper(i)) Mask[i] = Mask[tolower(i)]; 
  240.     return(M);
  241. }
  242.  
  243.